<?php
declare (strict_types=1);

namespace app\middleware;

use thans\jwt\exception\JWTException;
use thans\jwt\exception\TokenExpiredException;
use thans\jwt\facade\JWTAuth;
use think\facade\Log;

class Token
{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        $path = $request->pathinfo();
        if (preg_match('/login/', $path)) {
            if (config('base.cbc')) $this->parse($request);
            return $next($request);
        }
        try {
            if (config('base.cbc')) {
                $exist = $this->parse($request);
                if ($exist) {
                    if ($exist == 1) {
                        uapi_exit('key is abnormal');
                    } else {
                        uapi_exit('data is abnormal');
                    }
                }
            }
            $data = JWTAuth::auth();
            $request->account_info = $data;
            return $next($request);
        } catch (TokenNeedRefeshException $e) {
            Log::record($e->getMessage());
            uapi_exit('请先登录');
        } catch (TokenExpiredException $e) {
            Log::record($e->getMessage());
            uapi_exit('登录信息已过期，请重新登陆');
        } catch (JWTException $e) {
            uapi_exit('请先登录');
        }
    }

    public function parse($request)
    {
        if (empty($time)) $time = date('YmdHis', time());
        if (abs(strtotime(date($time)) - time()) >= 10) throw new \Exception('请核对您设备时间', '10000');
        $key = config('cbc.key');
        $iv = config('cbc.secret');
        $test = openssl_decrypt(base64_decode($request->param(config('sign'))), "AES-128-CBC", $key, 1, $iv);
        $test = htmlspecialchars_decode($test);
        $test = json_decode($test, true);
        $validate = $request->except([config('base.sign')]);
        $validate_array = array_keys($validate);
        foreach ($test as $KEY => $V) {
            if (!in_array($KEY, $validate_array)) {
                return 1;
            }
            foreach ($validate as $k => $value) {
                if ($KEY == $k) {
                    if ($V != $value) {
                        return 2;
                    }
                }
            }
        }
        return 0;
    }
}
